using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Text;
using System.Web;
using Newtonsoft.Json;

namespace OpenWaves.ActivityFeed.Web.Handler
{
    public class Browser
    {
        private readonly ActivityFeedApiHandler handler;

        public Browser(ActivityFeedApiHandler handler)
        {
            this.handler = handler;
        }

        public HttpResponseBase Get(string path)
        {
            using (var request = CreateRequestStub("GET", path))
            {
                return this.InvokeHandler(request);
            }
        }

        public HttpResponseBase PostJson(string path, object body)
        {
            using (var request = CreateRequestStub("POST", path, body))
            {
                return this.InvokeHandler(request);
            }
        }

        public HttpResponseBase Delete(string path)
        {
            using (var request = CreateRequestStub("DELETE", path))
            {
                return this.InvokeHandler(request);
            }
        }

        private static HttpRequestStub CreateRequestStub(string method, string path)
        {
            return CreateRequestStub(method, path, null);
        }

        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
        private static HttpRequestStub CreateRequestStub(string method, string path, object body)
        {
            var inputStream = new MemoryStream();
            var serializer = JsonSerializer.Create(JsonNetSerializerSettings.Current);
            using (var streamWriter = new StreamWriter(new UnclosableStream(inputStream), Encoding.UTF8))
            {
                serializer.Serialize(streamWriter, body);
            }

            inputStream.Seek(0, SeekOrigin.Begin);

            var request = new HttpRequestStub(method, new Uri(path, UriKind.Relative), inputStream)
                              {
                                  ContentEncoding = Encoding.UTF8,
                                  ContentType = "application/json"
                              };
            return request;
        }

        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
        private HttpResponseStub InvokeHandler(HttpRequestStub request)
        {
            var outputStream = new MemoryStream();
            var response = new HttpResponseStub(outputStream);
            this.handler.ProcessRequest(new HttpContextStub(request, response));
            outputStream.Seek(0, SeekOrigin.Begin);
            return response;
        }
    }
}